package com.heu.blood.charge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heu.blood.charge.dictenum.BloodChargeResultEnum;
import com.heu.blood.charge.entity.BloodChargeUploadHistoryEntity;
import com.heu.blood.charge.service.BloodChargeUploadHistoryService;
import com.heu.blood.charge.vo.BloodChargeEntityVo;
import com.heu.blood.charge.vo.BloodChargeHistoryUploadVo;
import com.heu.blood.common.enums.BloodChargeEnum;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.match.dao.BloodInformationDao;
import com.heu.blood.match.entity.BloodInformationEntity;
import com.heu.blood.match.exception.TimeException;

import com.heu.blood.storge.dao.BloodInStorgeDao;
import com.heu.blood.storge.entity.BloodInStorgeEntity;
import com.heu.blood.storge.exception.InstorageException;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;

import com.heu.blood.charge.dao.BloodChargeDao;
import com.heu.blood.charge.entity.BloodChargeEntity;
import com.heu.blood.charge.service.BloodChargeService;
import org.springframework.transaction.annotation.Transactional;

import static com.heu.blood.common.enums.CommonEnum.IF_SHOW;

@Service("bloodChargeService")
public class BloodChargeServiceImpl extends ServiceImpl<BloodChargeDao, BloodChargeEntity> implements BloodChargeService {

    @Autowired
    BloodChargeUploadHistoryService bloodChargeUploadHistoryService;

    @Autowired
    private BloodInStorgeDao bloodInStorgeDao;

    @Autowired
    private BloodChargeService bloodChargeService;

    @Override
    public PageUtils queryPage(BloodChargeEntityVo bloodChargeEntityVo) {
        if (bloodChargeEntityVo.getChargeState() != null) {
            switch (bloodChargeEntityVo.getChargeState()) {
                case "0":
                    bloodChargeEntityVo.setChargeState(BloodChargeEnum.CHARGE_UNVERIFIED.code());
                    break;
                case "1":
                    bloodChargeEntityVo.setChargeState(BloodChargeEnum.CHARGE_VERIFIED.code());
                    break;
                case "2":
                    bloodChargeEntityVo.setChargeState(BloodChargeEnum.CHARGE_SUBMITTED.code());
                    break;
                default:
                    break;
            }
        }

        // 时间格式化，解决Date->String 报错
        String startTime = bloodChargeEntityVo.getStartTime();
        String endTime = bloodChargeEntityVo.getEndTime();

        if (Strings.isNotBlank(startTime) && Strings.isNotBlank(endTime)) {
            if (startTime.compareTo(endTime) > 0) {
                throw new MyException(TimeException.TIME_OUTLINE);
            }
        }
        LambdaQueryWrapper<BloodChargeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodChargeEntityVo.getPatientId()), BloodChargeEntity::getPatientId, bloodChargeEntityVo.getPatientId())
                .eq(Strings.isNotBlank(bloodChargeEntityVo.getPatientName()), BloodChargeEntity::getPatientName, bloodChargeEntityVo.getPatientName())
                .eq(Strings.isNotBlank(bloodChargeEntityVo.getWard()),BloodChargeEntity::getWard,bloodChargeEntityVo.getWard())
                .eq(Strings.isNotBlank(bloodChargeEntityVo.getDepartment()),BloodChargeEntity::getDepartment,bloodChargeEntityVo.getDepartment())
                .eq(Strings.isNotBlank(bloodChargeEntityVo.getApplyDepartment()),BloodChargeEntity::getApplyDepartment,bloodChargeEntityVo.getApplyDepartment())
                .eq(Strings.isNotBlank(bloodChargeEntityVo.getPayment()),BloodChargeEntity::getPayment,bloodChargeEntityVo.getPayment())
                .eq(Strings.isNotBlank(bloodChargeEntityVo.getChargeState()), BloodChargeEntity::getChargeState, bloodChargeEntityVo.getChargeState())
                .ge(Strings.isNotBlank(bloodChargeEntityVo.getStartTime()), BloodChargeEntity::getGmtCreate, bloodChargeEntityVo.getStartTime())
                .le(Strings.isNotBlank(bloodChargeEntityVo.getEndTime()), BloodChargeEntity::getGmtCreate, bloodChargeEntityVo.getEndTime())
                .eq(BloodChargeEntity::getIfShow, IF_SHOW.code());


        Map<String, Object> params = new HashMap<>();
        if (Strings.isNotBlank(bloodChargeEntityVo.getLimit())){
            params.put("limit", bloodChargeEntityVo.getLimit());
        }
        if (Strings.isNotBlank(bloodChargeEntityVo.getPage())){
            params.put("page", bloodChargeEntityVo.getPage());
        }

        queryWrapper.orderByDesc(BloodChargeEntity::getGmtCreate);

        IPage<BloodChargeEntity> page = this.page(
                new Query<BloodChargeEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public int upload(BloodChargeHistoryUploadVo bloodChargeHistoryUploadVo) {
//        1.ids存的都是状态为CHARGE_VERIFIED 我们需要将标志位转为CHARGE_SUBMITTED 表示该条记录已经被上传
//        2.事务注解 将推送记录放到推送记录表中
//        3.return结果解析 a.JSON转换失败，返回0 b.保存成功，返回1 c.保存失败，返回2 d.ids为空或长度为0，返回3 e.IDS里是否状态不全是CHARGE_VERIFIED的 返回4
        QueryWrapper<BloodChargeEntity> queryWrapper = new QueryWrapper<>();
        Integer[] idsArray = bloodChargeHistoryUploadVo.getIds();
        // 判断 ids 是否为空或长度是否为0
        if (idsArray != null && idsArray.length > 0) {
            // 将数组转换为集合
            Collection<Integer> idsCollection = Arrays.asList(idsArray);

            // 调用 queryWrapper.in 方法
            queryWrapper.in("id", idsCollection);
            List<BloodChargeEntity> list = this.list(queryWrapper);

            for (BloodChargeEntity entity: list) {
                if (!BloodChargeEnum.CHARGE_VERIFIED.code().equals(entity.getChargeState())) {
//                    throw new RuntimeException("Not all IDs are in CHARGE_VERIFIED state");
                    return 4;
                }
//            标志位转为CHARGE_SUBMITTED
                entity.setChargeState(BloodChargeEnum.CHARGE_SUBMITTED.code());
                //TODO: 调用人家的his系统
            }


            // 将查询到的所有处于待上传状态的信息转换为JSON格式
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonString = "";
            try {
                jsonString = objectMapper.writeValueAsString(list);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                return 0; // JSON转换失败，返回0
            }
            BloodChargeUploadHistoryEntity bloodChargeUploadHistory = new BloodChargeUploadHistoryEntity();
            bloodChargeUploadHistory.setChargeInfo(jsonString);
            if (bloodChargeHistoryUploadVo.getOperatorId() != null) {
                bloodChargeUploadHistory.setOperatorId(bloodChargeHistoryUploadVo.getOperatorId());
            }
            if (bloodChargeHistoryUploadVo.getOperatorName() != null) {
                bloodChargeUploadHistory.setOperatorName(bloodChargeHistoryUploadVo.getOperatorName());
            }
//          放到这的目的是记录未修改状态之前的，万一到时候出了什么问题，好方便查错，比如可能出现你的状态是CHARGE_UNVERIFIED变成CHARGE_SUBMITTED
            if (!list.isEmpty()) {
                this.updateBatchById(list);
            }
//            json和操作人、操作人ID放到推送记录表中
            boolean saveResult = bloodChargeUploadHistoryService.save(bloodChargeUploadHistory);

            if (saveResult) {
                return 1; // 保存成功，返回1
            } else {
                return 2; // 保存失败，返回2
            }
        }
        return 3; // ids为空或长度为0，返回3
    }

    @Override
    public int saveBloodCharge(BloodChargeEntityVo bloodChargeEntityVo) {
//                if(StringUtils.isBlank(bloodChargeEntityVo.getPatientId())
//        || StringUtils.isBlank(bloodChargeEntityVo.getPatientName())
//        || StringUtils.isBlank(bloodChargeEntityVo.getWard())
//        || StringUtils.isBlank(bloodChargeEntityVo.getAge())
//        || StringUtils.isBlank(bloodChargeEntityVo.getDepartment())
//        || StringUtils.isBlank(bloodChargeEntityVo.getGender())){
//            return 1;
//        }

        BloodChargeEntity bloodChargeEntity = new BloodChargeEntityVo();
        BeanUtils.copyProperties(bloodChargeEntityVo, bloodChargeEntity);
        boolean b = this.save(bloodChargeEntity);
        return 0;
    }

    @Override
    public boolean saveCharge(BloodChargeEntity bloodCharge) {
        BloodChargeEntity bloodChargeEntity = new BloodChargeEntity();
        BeanUtils.copyProperties(bloodCharge, bloodChargeEntity);
        String bloodId = bloodChargeEntity.getBloodId();
        LambdaQueryWrapper<BloodInStorgeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BloodInStorgeEntity::getBloodId,bloodId);
        BloodInStorgeEntity bloodInStorgeEntity = bloodInStorgeDao.selectOne(queryWrapper);
        if(bloodInStorgeEntity == null){
            throw new MyException(InstorageException.NO_BLOODID_STORAGE);
        }
        return this.save(bloodChargeEntity);
    }

    @Override
    @Transactional
    public int verifySuccess(List<BloodChargeEntity> bloodCharge) {
        for (BloodChargeEntity entity : bloodCharge) {
            // 设置状态为已核对
            entity.setChargeState(BloodChargeEnum.CHARGE_VERIFIED.code());
            // 设置核验结果为成功
            entity.setChargeResult(BloodChargeResultEnum.SUCCESS.code());
        }
        boolean result = bloodChargeService.updateBatchById(bloodCharge);
        return result ? bloodCharge.size() : 0;
    }

    @Override
    @Transactional
    public int verifyFailure(List<BloodChargeEntity> bloodCharge) {
        for (BloodChargeEntity entity : bloodCharge) {
            // 设置状态为已核对
            entity.setChargeState(BloodChargeEnum.CHARGE_VERIFIED.code());
            // 设置核验结果为失败
            entity.setChargeResult(BloodChargeResultEnum.FAILURE.code());
        }
        boolean result = bloodChargeService.updateBatchById(bloodCharge);
        return result ? bloodCharge.size() : 0;
    }
}
